package server.core;

import server.*;
import server.connector.http.HttpRequestImpl;
import server.connector.http.HttpResponseImpl;
import server.util.LifecycleSupport;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;

public class SimpleWrapper implements Container, Lifecycle {
    private Servlet instance = null;
    //对于的Servlet类名
    private String servletClass;
    //wrapper的名称
    private String name;
    private SimpleLoader loader;
    private SimplePipeline pipeline = new SimplePipeline(this);
    private Container parent = null;
    //是否启动
    protected boolean started = false;
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
    public SimpleWrapper() {
        pipeline.setBasic(new SimpleWrapperValve());
    }

    public synchronized void addValve(Valve valve) {
        pipeline.addValve(valve);
    }

    public Servlet allocate() throws ServletException {
        if (instance == null) {
            try {
                instance = loadServlet();
            } catch (ServletException e) {
                throw e;
            } catch (Throwable t) {
                throw new ServletException("Cannot allocate a servlet instance", t);
            }
        }
        return instance;
    }
    private Servlet loadServlet() throws ServletException {
        if (instance != null)
            return instance;
        Servlet servlet = null;
        String actualClass = servletClass;
        if (actualClass == null) {
            throw new ServletException("servlet class has not been specified");
        }
        SimpleLoader loader = getLoader();
        if (loader == null) {
            throw new ServletException("No loader.");
        }
        ClassLoader classLoader = loader.getClassLoader();
        Class classClass = null;
        try {
            if (classLoader != null)
                classClass = classLoader.loadClass(actualClass);
        } catch (ClassNotFoundException e) {
            throw new ServletException("Servlet class not found");
        }
        try {
            servlet = (Servlet) classClass.newInstance();
        } catch (Throwable e) {
            throw new ServletException("Failed to instantiate servlet");
        }
        try {
            servlet.init(null);
        } catch (Throwable e) {
            throw new ServletException("Failed initialize servlet.");
        }
        return servlet;
    }

    //getter-------------------------------------------------------------------------------
    @Override
    public SimpleLoader getLoader() {
        if (loader != null)
            return loader;
        if (parent != null)
            return parent.getLoader();
        return null;
    }

    @Override
    public void invoke(HttpRequestImpl request, HttpResponseImpl response) throws IOException, ServletException {
        pipeline.invoke(request, response);
    }

    public String getName() {
        return name;
    }
    public Container getParent() {
        return parent;
    }
    public Valve getBasic() {
        return pipeline.getBasic();
    }
    public Valve[] getValves() {
        return pipeline.getValves();
    }
    //setter-------------------------------------------------------------------------------
    public void setLoader(SimpleLoader loader) {
        this.loader = loader;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setParent(Container container) {
        parent = container;
    }
    public void setServletClass(String servletClass) {
        this.servletClass = servletClass;
    }
    public void setBasic(Valve valve) {
        pipeline.setBasic(valve);
    }

    //实现Lifecycle接口-------------------------------------------------------------------------
    @Override
    public void addLifecycleListener(LifecycleListener listener) {

    }

    @Override
    public LifecycleListener[] findLifecycleListeners() {
        return null;
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {

    }

    @Override
    public void start() throws LifecycleException {
        System.out.println("Starting Wrapper " + name);
        if (started)
            throw new LifecycleException("Wrapper already started");
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        started = true;
        //启动加载器
        if (loader != null && loader instanceof Lifecycle) {
            ((Lifecycle) loader).start();
        }
        //启动管道
        if (pipeline instanceof Lifecycle)
            ((Lifecycle) pipeline).start();
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
    }

    @Override
    public void stop() throws LifecycleException {
        System.out.println("Stopping wrapper " + name);
        try {
            instance.destroy();
        } catch (Throwable t) {

        }
        instance = null;
        if (!started)
            throw new LifecycleException("Wrapper " + name + " not started");
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        if (pipeline instanceof Lifecycle) {
            ((Lifecycle) pipeline).stop();
        }
        if ((loader != null) && (loader instanceof Lifecycle)) {
            ((Lifecycle) loader).stop();
        }
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
    }
}
